package o2o.web.actions.wallet;

import com.google.gson.Gson;
import com.jinyou.utils.common.DateUtils;
import com.jinyou.utils.common.JYMathDoubleUtils;
import com.jinyou.utils.common.ValidateUtil;
import com.jinyouapp.cloud.pay.JyPayClient;
import com.jinyouapp.cloud.pay.exception.PayTransferException;
import exception.O2oTransferPayException;
import map.HttpRequest;
import notice.dao.NoticeType;
import o2o.cache.order.OrderPayMemory;
import o2o.cache.sys.SysCustomerCache;
import o2o.cache.wallet.UserWalletFlowMemory;
import o2o.cache.wallet.UserWalletMemory;
import o2o.config.dao.UserDaoSql;
import o2o.dao.PO.PojoTables;
import o2o.dao.PO.common.ResultInfo;
import o2o.dao.PO.common.UserType;
import o2o.dao.PO.device.door.DeviceCompanyContact;
import o2o.dao.PO.order.OrderPayInfo;
import o2o.dao.PO.user.UserInfo;
import o2o.dao.PO.wallet.UserWallet;
import o2o.dao.PO.wallet.UserWalletFlow;
import o2o.dao.PO.wallet.UserWalletFlowType;
import o2o.dao.PO.wallet.UserWalletPop;
import o2o.system.data.SYS_CONFIG_PATH;
import o2o.system.data.SYS_SETTINGS;
import o2o.web.actions.notice.Notice;
import o2o.web.actions.shop.ShopWalletMan;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

// 用户余额
public class UserWalletMan {
    public final static int ADD = 1;//增加余额
    public final static int POP_REFUSE = 12;// 拒绝提现
    public final static int REFUND_ADD = 11;//增加余额
    public final static int POP = 2;//提现申请
    public final static int POP_SUCCESS = 3;//提现成功
    public final static int REFUND = 4;//充值退款，减少钱包金额
    public final static int PAY = 5;//余额支付
    public final static int DEPOSIT_IN = 6;//押金增加
    public final static int DEPOSIT_OUT = 7;//押金减少
    public final static int DEPOSIT_FORCE_OUT = 8;//扣除押金减少
    //    public final static int Coupon_RedEnvelope = 9;//红包增加
    public final static int RED_PACKET_IN = 9;// 红包增加
    public final static int RED_PACKET_OUT = 21;// 红包减
    public final static int STATEMENT_DAO_ZHANG = 25;// 账单审核到账

    // 自动打款流程(支持微信/支付宝转账)
    synchronized public static void alipayOrWxTransfer(String username, UserInfo userInfo, UserWalletPop pop, Double actualTransferMoney, String opUser) throws Exception {
        if (StringUtils.isEmpty(pop.getChannel()) || (!pop.getChannel().equals("alipay")) && !pop.getChannel().equals("wx")) {
            throw new O2oTransferPayException("转账方式错误！");
        }
        String sysCustomer = SysCustomerCache.getInstance().getDefaultKey();
        if (StringUtils.isEmpty(sysCustomer)) {
            throw new O2oTransferPayException("系统标识不能为空");
        }
        String wxOpenIdStr = "";
        String uu = null;
        String realName = null;
        if (pop.getChannel().equals("wx")) {
//            if (StringUtils.isEmpty(userInfo.getWxOpenId())) {
//                throw new O2oTransferPayException("当前用户尚未绑定微信，请手动操作！");
//            }
//            uu = userInfo.getWxOpenId();
//            realName = pop.getTenpayRealName();
            if (StringUtils.isEmpty(pop.getTenpayopenId())) {
                throw new O2oTransferPayException("当前用户尚未绑定微信，请手动操作！");
            }
            uu = pop.getTenpayopenId();
            realName = pop.getTenpayRealName();
            wxOpenIdStr = ",tenpayopenId = '" + uu + "'";
        } else if (pop.getChannel().equals("alipay")) {
            uu = pop.getAlipay();
            realName = pop.getAlipayRealName();
        }
        Connection con = null;
        try {
            con = UserDaoSql.getInstance().getConnection();
            con.setAutoCommit(false);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        String out_trade_no = sysCustomer + pop.getId();
        Long time = DateUtils.getCurrTime();
        StringBuilder sb = new StringBuilder();
        sb.append("update ").append(PojoTables.USER_WALLET_POP).append(" set isDone = 1,updateUser = '").append(opUser)
                .append("',popTime = ").append(time)
                .append(",actualTransferMoney = ").append(actualTransferMoney)
                .append(",isAutoTransfer = 1").append(wxOpenIdStr)
                .append(",outTradeNo = '").append(out_trade_no).append("'")
                .append(" where id =").append(pop.getId()).append(" and username = '").append(username).append("' and isDone = 0 and delFlag = 0");

        try {
            UserDaoSql.getInstance().executeBySql(sb.toString(), con);
            UserWalletMan.alipayOrWxTransferUpdateUserWallet(username, ShopWalletMan.POP_SUCCESS, pop.getMoney(), opUser, con);
            // 微信或者支付宝自动转账
            JyPayClient.getInstance().transfer(sysCustomer, out_trade_no,
                    pop.getChannel(), actualTransferMoney, uu, realName, username, "1.1");
            con.commit();
        } catch (Exception e) {
            e.printStackTrace();
            UserDaoSql.getInstance().rollback(con);
            throw e;
        } finally {
            UserDaoSql.getInstance().close(con);
        }
        UserWalletMemory.getInstance().updateWallet(username);
        Notice.publishNotice2Person(null, username, userInfo.getUserType(), NoticeType.system, "提现申请", "您的提现申请已通过，预计3-5个工作日到账。");
    }

    public static void main(String[] args) {
        // 微信或者支付宝自动转账
        try {
            JyPayClient.getInstance().transfer("o2o-zhenwk", "zhenwk-456", "alipay", 0.1D, "yangke_0214@163.com", "杨克");
        } catch (PayTransferException e) {
//            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

    // 用户自动打款实现
    synchronized private static void alipayOrWxTransferUpdateUserWallet(String username, int type, Double money, String updateUser, Connection con) throws Exception {
        if (ValidateUtil.isNull(username)) {
            throw new Exception("用户账号不能为空");
        }
        if ((null == money || 0 == money)) {
            System.out.println("金额错误：" + username + " -- " + money);
            throw new Exception("金额错误");
        }

        Double fcMoney = money;
        if (null != SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && 0 == SYS_SETTINGS.USE_MAIN_CURRENCY_PAY) { //是否使用主币支付 1使用主币支付 0使用外币支付
            //外币支付需要转换
            //外币汇率
            if (ValidateUtil.isAbsDouble(SYS_SETTINGS.EXCHANGE_RATE)) {
                //外币计算
                fcMoney = JYMathDoubleUtils.mul(money, SYS_SETTINGS.EXCHANGE_RATE);
            }
        }
        UserWallet userWalletDB = UserWalletMemory.getInstance().getWallet(username);
        if (null == userWalletDB) {//账户不存在
            throw new Exception("账户不存在");
        }
        UserWallet userWallet = new UserWallet();
        BeanUtils.copyProperties(userWalletDB, userWallet);
        switch (type) {
            case POP_SUCCESS: {//提现成功
                //减少的金额是否不大于余额
                if (JYMathDoubleUtils.sub(userWallet.getPopMoney(), money) < 0) {
                    throw new Exception("提现金额超出申请金额");
                }
                userWallet.setPopMoney(JYMathDoubleUtils.sub(userWallet.getPopMoney(), money));//减少提现申请金额
                userWallet.setPopTotalMoney(JYMathDoubleUtils.add(userWallet.getPopTotalMoney(), money));//增加提现总金额
                //汇率
                if (null != SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && 0 == SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && ValidateUtil.isAbsDouble(SYS_SETTINGS.EXCHANGE_RATE)) {//是否使用主币支付 1使用主币支付 0使用外币支付
                    userWallet.setFcPopMoney(JYMathDoubleUtils.sub(userWallet.getFcPopMoney(), fcMoney));
                    userWallet.setFcPopTotalMoney(JYMathDoubleUtils.sub(userWallet.getFcPopTotalMoney(), fcMoney));
                }

                //保存到数据库
                StringBuilder sb = new StringBuilder();
                sb.append("update ").append(PojoTables.USER_WALLET).append(" set popMoney = ").append(userWallet.getPopMoney())
                        .append(",popTotalMoney = ").append(userWallet.getPopTotalMoney())
                        .append(",fcPopMoney=").append(userWallet.getFcPopMoney()).append(",fcPopTotalMoney=").append(userWallet.getFcPopTotalMoney())
                        .append(",updateUser = '").append(updateUser)
                        .append("' where username = '").append(username).append("' and delFlag = 0");
                try {
                    UserDaoSql.getInstance().executeBySql(sb.toString(), con);
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new Exception("申请失败，请稍后再试");
                }
//                //更新缓存
//                UserWalletMemory.getInstance().updateWallet(username);
            }
            break;
            case POP_REFUSE: {
                if (null == userWallet) {//账户不存在
                    throw new Exception("账户不存在");
                }
                //减少的金额是否不大于余额
                if (JYMathDoubleUtils.sub(userWallet.getPopMoney(), money) < 0) {
                    throw new Exception("提现金额超出申请金额");
                }

                userWallet.setPopMoney(JYMathDoubleUtils.sub(userWallet.getPopMoney(), money));//减少提现申请金额
                userWallet.setMoney(JYMathDoubleUtils.add(userWallet.getMoney(), money));//回退金额

                //货币金额转换
                if (null != SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && 0 == SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && ValidateUtil.isAbsDouble(SYS_SETTINGS.EXCHANGE_RATE)) {//是否使用主币支付 1使用主币支付 0使用外币支付
                    userWallet.setFcMoney(JYMathDoubleUtils.add(userWallet.getFcMoney(), fcMoney));
                    userWallet.setFcTotalMoney(JYMathDoubleUtils.add(userWallet.getFcTotalMoney(), fcMoney));
                }
                //保存到数据库
                StringBuilder sb = new StringBuilder();
                sb.append("update ").append(PojoTables.USER_WALLET).append(" set money = ").append(userWallet.getMoney())
                        .append(",totalMoney=").append(userWallet.getTotalMoney())
                        .append(",fcMoney=").append(userWallet.getFcMoney()).append(",fcTotalMoney=").append(userWallet.getFcTotalMoney())
                        .append(",popMoney=").append(userWallet.getPopMoney())
                        .append(",updateUser = '").append(updateUser).append("' where username = '").append(username).append("' and delFlag = 0");
                try {
                    UserDaoSql.getInstance().executeBySql(sb.toString(), con);
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new Exception("申请失败，请稍后再试");
                }
                //更新缓存
//                UserWalletMemory.getInstance().updateWallet(username);
            }
            break;
        }
    }

    public static ResultInfo saveOrUpdateUserWallet(String username, Integer userType, Long shopId, int type, Double money, Double awardMoney, String updateUser) {
        return saveOrUpdateUserWallet(username, userType, shopId, type, money, awardMoney, updateUser, null);
    }

    //更新余额
    synchronized public static ResultInfo saveOrUpdateUserWallet(String username, Integer userType, Long shopId, int type, Double money, Double awardMoney, String updateUser, String orderNo) {
        if (type != STATEMENT_DAO_ZHANG && ValidateUtil.isNull(username)) {
            return new ResultInfo("账号不能为空");
        }

//        if (ValidateUtil.isNotAbsDouble(money) && ValidateUtil.isNotAbsDouble(awardMoney)) {
//            return new ResultInfo("金额错误");
//        }
        if (type != STATEMENT_DAO_ZHANG && ((null == money || 0 == money) && (null == awardMoney || 0 == awardMoney))) {
            System.out.println("金额错误：" + username + " -- " + money + "," + awardMoney);
            return new ResultInfo("金额错误");
        }

        Double fcMoney = money;
        Double fcAwardMoney = awardMoney;
        if (null != SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && 0 == SYS_SETTINGS.USE_MAIN_CURRENCY_PAY) {//是否使用主币支付 1使用主币支付 0使用外币支付
            //外币支付需要转换
            //外币汇率
            if (ValidateUtil.isAbsDouble(SYS_SETTINGS.EXCHANGE_RATE)) {
                //外币计算
                fcMoney = JYMathDoubleUtils.mul(money, SYS_SETTINGS.EXCHANGE_RATE);
                fcAwardMoney = JYMathDoubleUtils.mul(awardMoney, SYS_SETTINGS.EXCHANGE_RATE);
            }
        }

        UserWallet userWallet = UserWalletMemory.getInstance().getWallet(username);
        Long time = DateUtils.getCurrTime();
        switch (type) {
            case STATEMENT_DAO_ZHANG: {       // 到账
                OrderPayInfo payInfo = OrderPayMemory.getInstance().get(orderNo);
                if (payInfo == null) {
                    return new ResultInfo("未获取到分成信息");
                }
                // 支付成功了
                if (payInfo.getSettlementState() == 1) {
                    return new ResultInfo();
                }
                List<UserWalletFlow> list = UserWalletFlowMemory.getInstance().searchUserWallet(orderNo, 0, 0);
                if (!ValidateUtil.isAbsList(list)) {
                    return new ResultInfo("流水信息异常");
                }
                UserWalletFlow flow = list.get(0);
                username = flow.getUsername();
                money = flow.getMoney() == null ? 0.0d : flow.getMoney();
                awardMoney = flow.getAwardMoney() == null ? 0.0d : flow.getAwardMoney();
                userWallet = UserWalletMemory.getInstance().getWallet(flow.getUsername());
                // 事务保存
                // todo 金额需要处理
                Connection con = null;
                try {
                    con = UserDaoSql.getInstance().getConnection();
                    con.setAutoCommit(false);
                    // i 增加一个人钱包数据
                    if (null == userWallet) {//账户不存在
                        //新建
                        userWallet = new UserWallet();
                        userWallet.setUsername(username);
                        userWallet.setShopId(payInfo.getSellerId());//如果是店铺的话才有店铺id
                        userWallet.setMoney(money);//余额
                        userWallet.setTotalMoney(money);//总金额
                        userWallet.setAwardMoney(awardMoney);//奖励金额
                        userWallet.setAwardTotalMoney(awardMoney);//奖励总金额
                        userWallet.setPopMoney(0d);//提现金额
                        userWallet.setPopTotalMoney(0d);//提现总金额
                        userWallet.setDelFlag(0);
                        userWallet.setCreateUser(updateUser);
                        userWallet.setCreateTime(time);
                        userWallet.setUserType(flow.getUserType());

                        //货币金额转换
                        if (payInfo.getUseMainCurrencyPay() == 0 && ValidateUtil.isAbsDouble(flow.getExchangeRate())) {//是否使用主币支付 1使用主币支付 0使用外币支付
                            //外币支付需要转换
                            //外币计算
                            fcMoney = JYMathDoubleUtils.mul(money, flow.getExchangeRate());
                            fcAwardMoney = JYMathDoubleUtils.mul(awardMoney, flow.getExchangeRate());

                            userWallet.setFcMoney(fcMoney);
                            userWallet.setFcTotalMoney(fcMoney);
                            userWallet.setFcPopMoney(0d);
                            userWallet.setFcPopTotalMoney(0d);
                            userWallet.setFcDepositMoney(0d);
                            userWallet.setFcAwardMoney(fcAwardMoney);
                            userWallet.setFcAwardTotalMoney(fcAwardMoney);
                        }

                        UserDaoSql.getInstance().saveObj(PojoTables.USER_WALLET, userWallet, con);
                    } else {
                        userWallet.setMoney(JYMathDoubleUtils.add(userWallet.getMoney(), money));
                        userWallet.setTotalMoney(JYMathDoubleUtils.add(userWallet.getTotalMoney(), money));
                        userWallet.setAwardMoney(JYMathDoubleUtils.add(userWallet.getAwardMoney(), awardMoney));
                        userWallet.setAwardTotalMoney(JYMathDoubleUtils.add(userWallet.getAwardTotalMoney(), awardMoney));

                        //货币金额转换
                        if (payInfo.getUseMainCurrencyPay() == 0 && ValidateUtil.isAbsDouble(flow.getExchangeRate())) {//是否使用主币支付 1使用主币支付 0使用外币支付
                            //外币计算
                            fcMoney = JYMathDoubleUtils.mul(money, flow.getExchangeRate());
                            fcAwardMoney = JYMathDoubleUtils.mul(awardMoney, flow.getExchangeRate());

                            userWallet.setFcMoney(JYMathDoubleUtils.add(userWallet.getFcMoney(), fcMoney));
                            userWallet.setFcTotalMoney(JYMathDoubleUtils.add(userWallet.getFcTotalMoney(), fcMoney));
                            userWallet.setFcAwardMoney(JYMathDoubleUtils.add(userWallet.getFcAwardMoney(), fcAwardMoney));
                            userWallet.setFcAwardTotalMoney(JYMathDoubleUtils.add(userWallet.getFcAwardTotalMoney(), fcAwardMoney));
                        }
                        StringBuilder sb = new StringBuilder();
                        sb.append("update ").append(PojoTables.USER_WALLET).append(" set money = ").append(userWallet.getMoney())
                                .append(",totalMoney=").append(userWallet.getTotalMoney()).append(",awardMoney=").append(userWallet.getAwardMoney()).append(",awardTotalMoney=").append(userWallet.getAwardTotalMoney())
                                .append(",fcMoney=").append(userWallet.getFcMoney()).append(",fcTotalMoney=").append(userWallet.getFcTotalMoney()).append(",fcAwardMoney=").append(userWallet.getFcAwardMoney()).append(",fcAwardTotalMoney=").append(userWallet.getFcAwardTotalMoney())
                                .append(",updateUser = '").append(updateUser).append("' where username = '").append(username).append("' and delFlag = 0");
                        System.out.println("用户余额增加，更新用户余额" + sb.toString());
                        UserDaoSql.getInstance().executeBySql(sb.toString(), con);
                    }
                    // ii 更新此单为已经打款
                    StringBuilder paySql = new StringBuilder();
                    paySql.append(" update ").append(PojoTables.OrderPay)
                            .append(" set settlementState = 1 ")
                            .append(" where orderNo = '").append(orderNo).append("'");
                    UserDaoSql.getInstance().executeBySql(paySql.toString(), con);
                    // iii 更新流水为已打款
                    StringBuilder walletSql = new StringBuilder();
                    walletSql.append(" update ").append(PojoTables.USER_WALLET_FLOW)
                            .append(" set state = 1 ")
                            .append(" where id = ").append(flow.getId());
                    UserDaoSql.getInstance().executeBySql(walletSql.toString(), con);
                    // 事务结束
                    con.commit();
                } catch (Exception e) {
                    e.printStackTrace();
                    UserDaoSql.getInstance().rollback(con);
                    return new ResultInfo(e.getMessage());
                } finally {
                    UserDaoSql.getInstance().close(con);
                }
                // 更新状态
                // i
                UserWalletMemory.getInstance().updateWallet(flow.getUsername());
                // ii
                UserWalletFlowMemory.getInstance().addFLow(flow.getOrderNo());
                // iii
                OrderPayMemory.getInstance().modify(flow.getOrderNo());
            }
            break;
            case RED_PACKET_IN:        // 红包增加
            case REFUND_ADD:        // 钱包支付退款
            case ADD: {//增加
                if (null == awardMoney) {
                    awardMoney = 0d;
                }
                if (null == userWallet) {//账户不存在
                    //新建
                    userWallet = new UserWallet();
                    userWallet.setUsername(username);
                    userWallet.setShopId(shopId);//如果是店铺的话才有店铺id
                    userWallet.setMoney(money);//余额
                    userWallet.setTotalMoney(money);//总金额
                    userWallet.setAwardMoney(awardMoney);//奖励金额
                    userWallet.setAwardTotalMoney(awardMoney);//奖励总金额
                    userWallet.setPopMoney(0d);//提现金额
                    userWallet.setPopTotalMoney(0d);//提现总金额
                    userWallet.setDelFlag(0);
                    userWallet.setCreateUser(updateUser);
                    userWallet.setCreateTime(time);
                    userWallet.setUserType(userType);

                    //货币金额转换
                    if (null != SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && 0 == SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && ValidateUtil.isAbsDouble(SYS_SETTINGS.EXCHANGE_RATE)) {//是否使用主币支付 1使用主币支付 0使用外币支付
                        userWallet.setFcMoney(fcMoney);
                        userWallet.setFcTotalMoney(fcMoney);
                        userWallet.setFcPopMoney(0d);
                        userWallet.setFcPopTotalMoney(0d);
                        userWallet.setFcDepositMoney(0d);
                        userWallet.setFcAwardMoney(fcAwardMoney);
                        userWallet.setFcAwardTotalMoney(fcAwardMoney);
                    }

                    try {
                        UserDaoSql.getInstance().insertObj(PojoTables.USER_WALLET, userWallet);
                    } catch (SQLException e) {
                        e.printStackTrace();
                        return new ResultInfo("处理失败，请稍后再试");
                    }
                } else {
                    userWallet.setMoney(JYMathDoubleUtils.add(userWallet.getMoney(), money));
                    userWallet.setTotalMoney(JYMathDoubleUtils.add(userWallet.getTotalMoney(), money));
                    userWallet.setAwardMoney(JYMathDoubleUtils.add(userWallet.getAwardMoney(), awardMoney));
                    userWallet.setAwardTotalMoney(JYMathDoubleUtils.add(userWallet.getAwardTotalMoney(), awardMoney));

                    //货币金额转换
                    if (null != SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && 0 == SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && ValidateUtil.isAbsDouble(SYS_SETTINGS.EXCHANGE_RATE)) {//是否使用主币支付 1使用主币支付 0使用外币支付
                        userWallet.setFcMoney(JYMathDoubleUtils.add(userWallet.getFcMoney(), fcMoney));
                        userWallet.setFcTotalMoney(JYMathDoubleUtils.add(userWallet.getFcTotalMoney(), fcMoney));
                        userWallet.setFcAwardMoney(JYMathDoubleUtils.add(userWallet.getFcAwardMoney(), fcAwardMoney));
                        userWallet.setFcAwardTotalMoney(JYMathDoubleUtils.add(userWallet.getFcAwardTotalMoney(), fcAwardMoney));
                    }


                    StringBuilder sb = new StringBuilder();
                    sb.append("update ").append(PojoTables.USER_WALLET).append(" set money = ").append(userWallet.getMoney())
                            .append(",totalMoney=").append(userWallet.getTotalMoney()).append(",awardMoney=").append(userWallet.getAwardMoney()).append(",awardTotalMoney=").append(userWallet.getAwardTotalMoney())
                            .append(",fcMoney=").append(userWallet.getFcMoney()).append(",fcTotalMoney=").append(userWallet.getFcTotalMoney()).append(",fcAwardMoney=").append(userWallet.getFcAwardMoney()).append(",fcAwardTotalMoney=").append(userWallet.getFcAwardTotalMoney())
                            .append(",updateUser = '").append(updateUser).append("' where username = '").append(username).append("' and delFlag = 0");
                    System.out.println("用户余额增加，更新用户余额" + sb.toString());
                    try {
                        UserDaoSql.getInstance().executeBySql(sb.toString());
                    } catch (SQLException e) {
                        e.printStackTrace();
                        return new ResultInfo("处理失败，请稍后再试");
                    }
                }

                //保存到缓存
                UserWalletMemory.getInstance().updateWallet(username);
            }
            break;
            case POP: {//提现申请
                if (null == userWallet) {//账户不存在
                    return new ResultInfo("账户不存在");
                }
                //减少的金额是否不大于余额
                if (JYMathDoubleUtils.sub(userWallet.getMoney(), money) < 0) {
                    return new ResultInfo("提现金额超出余额");
                }

                //减少
                userWallet.setMoney(JYMathDoubleUtils.sub(userWallet.getMoney(), money));//余额减少
                userWallet.setPopMoney(JYMathDoubleUtils.add(userWallet.getPopMoney(), money));//提现金额增加

                //汇率
                if (null != SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && 0 == SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && ValidateUtil.isAbsDouble(SYS_SETTINGS.EXCHANGE_RATE)) {//是否使用主币支付 1使用主币支付 0使用外币支付
                    userWallet.setFcMoney(JYMathDoubleUtils.sub(userWallet.getFcMoney(), fcMoney));
                    userWallet.setFcPopMoney(JYMathDoubleUtils.add(userWallet.getFcPopMoney(), fcMoney));
                }

                //保存到数据库
                StringBuilder sb = new StringBuilder();
                sb.append("update ").append(PojoTables.USER_WALLET).append(" set money = ").append(userWallet.getMoney())
                        .append(",popMoney = ").append(userWallet.getPopMoney())
                        .append(",fcMoney=").append(userWallet.getFcMoney()).append(",fcPopMoney=").append(userWallet.getFcPopMoney())
                        .append(",updateUser = '").append(updateUser)
                        .append("' where username = '").append(username).append("' and delFlag = 0");
                try {
                    UserDaoSql.getInstance().executeBySql(sb.toString());
                } catch (SQLException e) {
                    e.printStackTrace();
                    return new ResultInfo("申请失败，请稍后再试");
                }

                //更新缓存
                UserWalletMemory.getInstance().updateWallet(username);
            }
            break;
            case POP_SUCCESS: {//提现成功
                if (null == userWallet) {//账户不存在
                    return new ResultInfo("账户不存在");
                }
                //减少的金额是否不大于余额
                if (JYMathDoubleUtils.sub(userWallet.getPopMoney(), money) < 0) {
                    return new ResultInfo("提现金额超出申请金额");
                }

                userWallet.setPopMoney(JYMathDoubleUtils.sub(userWallet.getPopMoney(), money));//减少提现申请金额
                userWallet.setPopTotalMoney(JYMathDoubleUtils.add(userWallet.getPopTotalMoney(), money));//增加提现总金额

                //汇率
                if (null != SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && 0 == SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && ValidateUtil.isAbsDouble(SYS_SETTINGS.EXCHANGE_RATE)) {//是否使用主币支付 1使用主币支付 0使用外币支付
                    userWallet.setFcPopMoney(JYMathDoubleUtils.sub(userWallet.getFcPopMoney(), fcMoney));
                    userWallet.setFcPopTotalMoney(JYMathDoubleUtils.add(userWallet.getFcPopTotalMoney(), fcMoney));
                }

                //保存到数据库
                StringBuilder sb = new StringBuilder();
                sb.append("update ").append(PojoTables.USER_WALLET).append(" set popMoney = ").append(userWallet.getPopMoney())
                        .append(",popTotalMoney = ").append(userWallet.getPopTotalMoney())
                        .append(",fcPopMoney=").append(userWallet.getFcPopMoney()).append(",fcPopTotalMoney=").append(userWallet.getFcPopTotalMoney())
                        .append(",updateUser = '").append(updateUser)
                        .append("' where username = '").append(username).append("' and delFlag = 0");
                try {
                    UserDaoSql.getInstance().executeBySql(sb.toString());
                } catch (SQLException e) {
                    e.printStackTrace();
                    return new ResultInfo("申请失败，请稍后再试");
                }

                //更新缓存
                UserWalletMemory.getInstance().updateWallet(username);
            }
            break;
            case POP_REFUSE: {
                if (null == userWallet) {//账户不存在
                    return new ResultInfo("账户不存在");
                }
                //减少的金额是否不大于余额
                if (JYMathDoubleUtils.sub(userWallet.getPopMoney(), money) < 0) {
                    return new ResultInfo("提现金额超出申请金额");
                }

                userWallet.setPopMoney(JYMathDoubleUtils.sub(userWallet.getPopMoney(), money));//减少提现申请金额
                userWallet.setMoney(JYMathDoubleUtils.add(userWallet.getMoney(), money));//回退金额

                //货币金额转换
                if (null != SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && 0 == SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && ValidateUtil.isAbsDouble(SYS_SETTINGS.EXCHANGE_RATE)) {//是否使用主币支付 1使用主币支付 0使用外币支付
                    userWallet.setFcMoney(JYMathDoubleUtils.sub(userWallet.getFcMoney(), fcMoney));
                    userWallet.setFcTotalMoney(JYMathDoubleUtils.add(userWallet.getFcTotalMoney(), fcMoney));
                }


                //保存到数据库
                StringBuilder sb = new StringBuilder();
                sb.append("update ").append(PojoTables.USER_WALLET).append(" set money = ").append(userWallet.getMoney())
                        .append(",totalMoney=").append(userWallet.getTotalMoney())
                        .append(",fcMoney=").append(userWallet.getFcMoney()).append(",fcTotalMoney=").append(userWallet.getFcTotalMoney())
                        .append(",popMoney=").append(userWallet.getPopMoney())
                        .append(",updateUser = '").append(updateUser).append("' where username = '").append(username).append("' and delFlag = 0");
                try {
                    UserDaoSql.getInstance().executeBySql(sb.toString());
                } catch (SQLException e) {
                    e.printStackTrace();
                    return new ResultInfo("申请失败，请稍后再试");
                }
                //更新缓存
                UserWalletMemory.getInstance().updateWallet(username);
            }
            break;
            case REFUND: {//退款
                if (null == userWallet) {//账户不存在
                    return new ResultInfo("账户不存在，无法退款");
                }
                //减少的金额是否不大于余额
                if (JYMathDoubleUtils.sub(userWallet.getMoney(), money) < 0) {
                    return new ResultInfo("退款金额超出账户余额");
                }

                //减少
                userWallet.setMoney(JYMathDoubleUtils.sub(userWallet.getMoney(), money));
                userWallet.setTotalMoney(JYMathDoubleUtils.sub(userWallet.getTotalMoney(), money));

                //汇率
                if (null != SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && 0 == SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && ValidateUtil.isAbsDouble(SYS_SETTINGS.EXCHANGE_RATE)) {//是否使用主币支付 1使用主币支付 0使用外币支付
                    userWallet.setFcMoney(JYMathDoubleUtils.sub(userWallet.getFcMoney(), fcMoney));
                    userWallet.setFcTotalMoney(JYMathDoubleUtils.sub(userWallet.getFcTotalMoney(), fcMoney));
                }

                StringBuilder sb = new StringBuilder();
                sb.append("update ").append(PojoTables.USER_WALLET).append(" set money = ").append(userWallet.getMoney())
                        .append(",totalMoney=").append(userWallet.getTotalMoney())
                        .append(",fcMoney=").append(userWallet.getFcMoney()).append(",fcTotalMoney=").append(userWallet.getFcTotalMoney())
                        .append(",updateUser = '").append(updateUser)
                        .append("' where username = '").append(username).append("' and delFlag = 0");
                try {
                    UserDaoSql.getInstance().executeBySql(sb.toString());
                } catch (SQLException e) {
                    e.printStackTrace();
                    return new ResultInfo("处理失败，请稍后再试");
                }

                //更新缓存
                UserWalletMemory.getInstance().updateWallet(username);
            }
            break;
            case PAY: {//余额支付
                if (null == userWallet) {//账户不存在
                    return new ResultInfo("暂无余额，请选择其他支付方式");
                }

                //减少的金额是否不大于余额
//                if (JYMathDoubleUtils.sub(userWallet.getMoney(), money) < 0) {
//                    return new ResultInfo("您的余额不足，请选择其他支付方式");
//                }

                Double walletMoney = userWallet.getMoney();
                Double fcWalletMoney = userWallet.getFcMoney();
                Double walletAwardMoney = userWallet.getAwardMoney();
                Double fcWalletAwardMoney = userWallet.getFcAwardMoney();
                Double totalWalletMoney = JYMathDoubleUtils.add(walletMoney, walletAwardMoney);
                Double fcTotalWalletMoney = JYMathDoubleUtils.add(fcWalletMoney, fcWalletAwardMoney);
                //钱包可用余额是否够
                if (JYMathDoubleUtils.sub(totalWalletMoney, money) < 0) {
                    return new ResultInfo("您的余额不足，请选择其他支付方式");
                }

                if (JYMathDoubleUtils.sub(walletMoney, money) < 0) { //钱包余额不够 需要使用赠送金额
                    //先减掉余额
                    userWallet.setMoney(0d);
                    userWallet.setFcMoney(0d);
                    //剩下的从赠送金额里减
                    Double bMoney = JYMathDoubleUtils.sub(money, walletMoney);//需要在赠送里扣的
                    Double fcBMoney = JYMathDoubleUtils.sub(fcMoney, fcWalletMoney);//需要在赠送里扣的
                    userWallet.setAwardMoney(JYMathDoubleUtils.sub(walletAwardMoney, bMoney));
                    userWallet.setFcAwardMoney(JYMathDoubleUtils.sub(fcTotalWalletMoney, fcBMoney));
                } else {
                    //钱包余额够
                    userWallet.setMoney(JYMathDoubleUtils.sub(walletMoney, money));
                    userWallet.setFcMoney(JYMathDoubleUtils.sub(fcWalletMoney, fcMoney));
                }

                //减少
//                userWallet.setMoney(JYMathDoubleUtils.sub(userWallet.getMoney(), money));
//                userWallet.setTotalMoney(JYMathDoubleUtils.sub(userWallet.getTotalMoney(), money));

                StringBuilder sb = new StringBuilder();
                sb.append("update ").append(PojoTables.USER_WALLET).append(" set money = ").append(userWallet.getMoney())
                        .append(",awardMoney=").append(userWallet.getAwardMoney())
                        .append(",fcMoney=").append(userWallet.getFcMoney()).append(",fcAwardMoney=").append(userWallet.getFcAwardMoney())
                        .append(",updateUser = '").append(updateUser)
                        .append("' where username = '").append(username).append("' and delFlag = 0");
                try {
                    UserDaoSql.getInstance().executeBySql(sb.toString());
                } catch (SQLException e) {
                    e.printStackTrace();
                    return new ResultInfo("处理失败，请稍后再试");
                }

                //更新缓存
                UserWalletMemory.getInstance().updateWallet(username);
            }
            break;
            case DEPOSIT_IN: {//增加押金
                if (null == userWallet) {//账户不存在
                    //新建
                    userWallet = new UserWallet();
                    userWallet.setUsername(username);
                    userWallet.setShopId(shopId);//如果是店铺的话才有店铺id
                    userWallet.setDepositMoney(money);//押金金额
                    userWallet.setFcDepositMoney(fcMoney);//押金金额
                    userWallet.setMoney(0d);//余额
                    userWallet.setTotalMoney(0d);//总金额
                    userWallet.setPopMoney(0d);//提现金额
                    userWallet.setPopTotalMoney(0d);//提现总金额
                    userWallet.setDelFlag(0);
                    userWallet.setCreateUser(updateUser);
                    userWallet.setCreateTime(time);
                    userWallet.setUserType(userType);
                    try {
                        UserDaoSql.getInstance().insertObj(PojoTables.USER_WALLET, userWallet);
                    } catch (SQLException e) {
                        e.printStackTrace();
                        return new ResultInfo("处理失败，请稍后再试");
                    }
                } else {
                    userWallet.setDepositMoney(JYMathDoubleUtils.add(userWallet.getDepositMoney(), money));

                    StringBuilder sb = new StringBuilder();
                    sb.append("update ").append(PojoTables.USER_WALLET).append(" set depositMoney = ").append(userWallet.getDepositMoney())
                            .append(",fcDepositMoney=").append(userWallet.getFcDepositMoney())
                            .append(",updateUser = '").append(updateUser)
                            .append("' where username = '").append(username).append("' and delFlag = 0");
                    try {
                        UserDaoSql.getInstance().executeBySql(sb.toString());
                    } catch (SQLException e) {
                        e.printStackTrace();
                        return new ResultInfo("处理失败，请稍后再试");
                    }
                }

                //保存到缓存
                UserWalletMemory.getInstance().updateWallet(username);
            }
            break;
            case DEPOSIT_OUT://押金提现申请
            {
                if (null == userWallet) {//账户不存在
                    return new ResultInfo("账户不存在");
                }
                UserWallet userWallet1 = new UserWallet();
                BeanUtils.copyProperties(userWallet, userWallet1);
                //减少的金额是否不大于余额
                if (JYMathDoubleUtils.sub(userWallet1.getDepositMoney(), money) < 0) {
                    return new ResultInfo("提现金额超出押金余额");
                }

                //减少
                userWallet1.setDepositMoney(JYMathDoubleUtils.sub(userWallet1.getDepositMoney(), money));//余额减少
                userWallet1.setFcDepositMoney(JYMathDoubleUtils.sub(userWallet1.getFcDepositMoney(), fcMoney));//余额减少
                userWallet1.setPopTotalMoney(JYMathDoubleUtils.add(userWallet1.getPopTotalMoney(), money));//增加提现总金额
                //保存到数据库
                StringBuilder sb = new StringBuilder();
                sb.append("update ").append(PojoTables.USER_WALLET).append(" set depositMoney = ").append(userWallet1.getDepositMoney())
                        .append(",fcDepositMoney=").append(userWallet1.getFcDepositMoney())
                        .append(",updateUser = '").append(updateUser)
                        .append("' where username = '").append(username).append("' and delFlag = 0");
                try {
                    UserDaoSql.getInstance().executeBySql(sb.toString());
                } catch (SQLException e) {
                    e.printStackTrace();
                    return new ResultInfo("申请失败，请稍后再试");
                }
                //更新缓存
                UserWalletMemory.getInstance().updateWallet(username);
            }
            break;
            case DEPOSIT_FORCE_OUT: {//扣除押金
                if (JYMathDoubleUtils.sub(userWallet.getDepositMoney(), money) < 0) {
                    return new ResultInfo("提现金额超出押金余额");
                }
                //减少
                userWallet.setDepositMoney(JYMathDoubleUtils.sub(userWallet.getDepositMoney(), money));//余额减少
                userWallet.setFcDepositMoney(JYMathDoubleUtils.sub(userWallet.getFcDepositMoney(), fcMoney));//余额减少
                //保存到数据库
                StringBuilder sb = new StringBuilder();
                sb.append("update ").append(PojoTables.USER_WALLET).append(" set depositMoney = ").append(userWallet.getDepositMoney())
                        .append(",fcDepositMoney=").append(userWallet.getFcDepositMoney())
                        .append(",updateUser = '").append(updateUser)
                        .append("' where username = '").append(username).append("' and delFlag = 0");
                try {
                    UserDaoSql.getInstance().executeBySql(sb.toString());
                } catch (SQLException e) {
                    e.printStackTrace();
                    return new ResultInfo("申请失败，请稍后再试");
                }

                //更新缓存
                UserWalletMemory.getInstance().updateWallet(username);
            }
            break;
            case RED_PACKET_OUT: {// 退回用户的免单红包金额（减少赠送金额）
                if (null == userWallet) {//账户不存在
                    return new ResultInfo("账户不存在，无法减少");
                }
                Double walletMoney = userWallet.getMoney();
                Double fcWalletMoney = userWallet.getFcMoney();
                Double walletAwardMoney = userWallet.getAwardMoney();
                Double fcWalletAwardMoney = userWallet.getFcAwardMoney();
                Double totalWalletMoney = JYMathDoubleUtils.add(walletMoney, walletAwardMoney);
                Double fcTotalWalletMoney = JYMathDoubleUtils.add(fcWalletMoney, fcWalletAwardMoney);
                //钱包可用余额是否够
                if (JYMathDoubleUtils.sub(totalWalletMoney, money) < 0) {
                    return new ResultInfo("您的余额不足，请选择其他支付方式");
                }

                if (JYMathDoubleUtils.sub(walletAwardMoney, money) < 0) { //钱包赠送余额不够 需要使用余额
                    //先减掉余额
                    userWallet.setAwardMoney(0d);
                    //剩下的从余额里减
                    Double bMoney = JYMathDoubleUtils.sub(money, walletAwardMoney);//需要在余额里扣的
                    userWallet.setMoney(JYMathDoubleUtils.sub(walletMoney, bMoney));
                } else {
                    //钱包赠送金额够
                    userWallet.setAwardMoney(JYMathDoubleUtils.sub(walletAwardMoney, money));
                }

                //货币金额转换
                if (null != SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && 0 == SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && ValidateUtil.isAbsDouble(SYS_SETTINGS.EXCHANGE_RATE)) {//是否使用主币支付 1使用主币支付 0使用外币支付
                    if (JYMathDoubleUtils.sub(walletAwardMoney, money) < 0) { //钱包赠送余额不够 需要使用余额
                        //先减掉余额
                        userWallet.setFcAwardMoney(0d);
                        //剩下的从余额里减
                        Double fcBMoney = JYMathDoubleUtils.sub(fcMoney, fcWalletAwardMoney);//需要在赠送里扣的
                        userWallet.setFcMoney(JYMathDoubleUtils.sub(fcTotalWalletMoney, fcBMoney));
                    } else {
                        //钱包赠送金额够
                        userWallet.setFcAwardMoney(JYMathDoubleUtils.sub(fcWalletAwardMoney, fcMoney));
                    }
                }

                //减少
                StringBuilder sb = new StringBuilder();
                sb.append("update ").append(PojoTables.USER_WALLET).append(" set money = ").append(userWallet.getMoney())
                        .append(",awardMoney=").append(userWallet.getAwardMoney())
                        .append(",fcMoney=").append(userWallet.getFcMoney()).append(",fcAwardMoney=").append(userWallet.getFcAwardMoney())
                        .append(",updateUser = '").append(updateUser)
                        .append("' where username = '").append(username).append("' and delFlag = 0");
                try {
                    UserDaoSql.getInstance().executeBySql(sb.toString());
                } catch (SQLException e) {
                    e.printStackTrace();
                    return new ResultInfo("处理失败，请稍后再试");
                }

                //更新缓存
                UserWalletMemory.getInstance().updateWallet(username);
            }
            break;
        }


        return new ResultInfo();
    }

    // todo 提现到余额
    public static ResultInfo distributeMoneyPop2Wallet(String username, double cash, String opUser) {
        String parentId = null;
        try {
            parentId = popDistributeMoney(username, cash);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResultInfo(e.getMessage());
        }
        UserWalletFlow shopFlow = new UserWalletFlow(username, UserType.USER, parentId == null ? "" : parentId + "", 9, cash,
                cash, 1.0, UserWalletFlowType.FLOW_INCOME,
                opUser, DateUtils.getCurrTime());
        //汇率
        if (null != SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && 0 == SYS_SETTINGS.USE_MAIN_CURRENCY_PAY && ValidateUtil.isAbsDouble(SYS_SETTINGS.EXCHANGE_RATE)) {//是否使用主币支付 1使用主币支付 0使用外币支付
            shopFlow.setExchangeRate(SYS_SETTINGS.EXCHANGE_RATE);
            shopFlow.setFcOrderTotalMoney(JYMathDoubleUtils.mul(cash, SYS_SETTINGS.EXCHANGE_RATE));
            shopFlow.setFcMoney(JYMathDoubleUtils.mul(cash, SYS_SETTINGS.EXCHANGE_RATE));
        }
        try {
            UserDaoSql.getInstance().insertObj(PojoTables.USER_WALLET_FLOW, shopFlow);
        } catch (SQLException e) {
            e.printStackTrace();
            return new ResultInfo("创建店铺分配流水失败.");
        }
        // 增加用户的余额
        ResultInfo resultInfo = UserWalletMan.saveOrUpdateUserWallet(username, UserType.USER, null, UserWalletMan.ADD, cash, 0d, opUser);
        if (null == resultInfo || !resultInfo.isSuccess()) {
            System.out.println("更新用户余额错误:" + resultInfo == null ? "" : resultInfo.getError());
            try {
                cancelDistributeMoney(username, parentId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return new ResultInfo();
    }

    // todo: 远程提现分销费用
    private static String popDistributeMoney(String username, double cash) throws Exception {
        String requestStr = HttpRequest.sendPost(SYS_CONFIG_PATH.FEN_XIAO_SERVICE_URL + "/api/distribute/user/cash/add-wallet"
                , "username=" + username + "&cash=" + cash + "&sysCustomer=" + SYS_CONFIG_PATH.FEN_XIAO_SERVICE_KEY);
        DeviceCompanyContact companyContact = new Gson().fromJson(requestStr, DeviceCompanyContact.class);
        if (null == companyContact || 0 == companyContact.getStatus()) {
            throw new Exception(ValidateUtil.isNotNull(companyContact.getError()) ? companyContact.getError() : "提现失败,请稍后重试");
        }
        if (0 == 1 - companyContact.getStatus()) {
            if (companyContact.getInfo() != null) {
                return companyContact.getInfo().toString();
            }
        }
        return null;
    }

    // todo: 分销提现回退
    private static void cancelDistributeMoney(String username, String id) throws Exception {
        if (ValidateUtil.isNull(id)) {
            return;
        }
        String requestStr = HttpRequest.sendPost(SYS_CONFIG_PATH.FEN_XIAO_SERVICE_URL + "/api/distribute/user/cash/add-wallet/fail/back"
                , "username=" + username + "&id=" + id + "&sysCustomer=" + SYS_CONFIG_PATH.FEN_XIAO_SERVICE_KEY);
        DeviceCompanyContact companyContact = new Gson().fromJson(requestStr, DeviceCompanyContact.class);
        if (null == companyContact || 0 == companyContact.getStatus()) {
            throw new Exception(ValidateUtil.isNotNull(companyContact.getError()) ? companyContact.getError() : "操作失败,请稍后重试");
        }
        if (0 == 1 - companyContact.getStatus()) {
            System.out.println("分销提现回退处理成功~");
        }
    }
}
